import socket, sys, threading
from Tkinter import *
from partie import *
import re
# dictionnaire des connexions clients
listeJoueur = {}  
# liste des parties en cours
listePartie=[]


class ThreadClient(threading.Thread):
    #initialisation de la thread
    def __init__(self, conn):
        threading.Thread.__init__(self)
        #memorisation de la thread
        self.connexion = conn

    #boucle principale
    def run(self):
        #memorisation du numero de la thread (identifiant unique)
        nom = self.getName()
        #boucle de reception des messages
        while 1:
            #connexion des clients
            #4000 : taille maximale des donnees
            msgClient = self.connexion.recv(4000)
            print "**%s** de %s" % (msgClient, nom)

            deb = msgClient.split(',')[0]
            if re.search("^listePartiesEnAttente",msgClient)!=None:
                #recherche des parties en attente
                n=0
                j=0
                c=""
                for i in listePartie:
                    print i.etat
                    if i.etat==-1:
                        #-1 : partie en attente de joueur
                        n+=1
                        if c=="":
                            c=str(j)+","+i.getinfo()
                        else :
                            c=c+";"+str(j)+","+i.getinfo()
                    j+=1
                #envoie de la liste des parties en attente
                listeJoueur[nom].send("nbPartiesEnAttente\n"+str(n)+"\n"+"ListePartiesEnAttente\n"+c)       
                
            if re.search("^numPartieChoisie",msgClient)!=None:
                #print "numpartiechoisie"
                #ajout du joueur a la partie choisie
                if len(msgClient)>len("numPartieChoisie\n"):
                    msg,msg2,msg3,msg4=msgClient.split("\n")
                self.numPartie=int(msg2)
                if msg3!="nomJoueur":
                    print "etrange !!!!"
                listePartie[int(msg2)].addjoueur(msg4,self.connexion)

            if re.search("^partie",msgClient):
                #creation d'une nouvelle partie
                #print "partie"
                #print msgClient
                if len(msgClient)>len("partie\n"):
                    msg,msg2=msgClient.split("\n")
                #creation de la partie
                #print msg2
                listePartie.append(Partie(msg2,listeJoueur[nom]))
                #association de la thread a une partie
                #print "creation partie"
                #print len(listePartie)
                #print listePartie[len(listePartie)-1].getetat()
                self.numPartie=len(listePartie)-1

            if re.search("^matrice",msgClient):
                #print "mamatrice"
                #print msgClient
                #if len(msgClient)>len("matrice\n"):
                #    msg,msg2=msgClient.split("\n")
                listePartie[self.numPartie].message(self.connexion,msgClient)
              #     listePartie[self.numPartie].emiMatrice(self.emission,msg2)

              # if (msgClient=="bombeDecouverte"):
              #     listePartie[self.numPartie].bombe(self.emission)


            if re.search("^clic",msgClient):
                #print "clic"
                #print msgClient
                #on test si c'est a se joueur de jouer
                #if listePartie[self.num].quijoue(self.emission):
                #if (len(testmsg)==2 & type(int(testmsg[0]))==int & type(int(testmsg[1]))==int):
                listePartie[self.numPartie].clic(self.connexion,msgClient)
                #listePartie[self.numPartie].message(self.connexion,"toi")
                #for i in range(100):
                #    listePartie[self.numPartie].tour()
                #listeJoueur[nom].send("toi")
                #listeJoueur[nom]==self.connexion
                #else :
                #self.emission.send("Pb_PasToi")
                          
                
            if re.search("^modificationCompteur",msgClient):
#renvoie du message a tout les autres joueurs de la parties
                listePartie[self.numPartie].message(self.connexion,msgClient)

            if re.search("^finPartie",msgClient):
                #renvoie du message a tout les autres joueurs de la parties
                listePartie[self.numPartie].message(self.connexion,msgClient)  
                
            if re.search("^aPerdu",msgClient):
                #renvoie du message a tout les autres joueurs de la parties
                listePartie[self.numPartie].message(self.connexion,msgClient)
            if re.search("^pass",msgClient):
                #passe le tour de jeu
                listePartie[self.numPartie].tour() 

            if re.search("^quitte",msgClient):
                #gestion de deconnexion d'un joueur
                listePartie[self.numPartie].deljoueur(self.connexion)             

            if msgClient.upper() == "FIN" or msgClient =="":
                break
            #message = "%s> %s" % (nom, msgClient)
            #print message
            # Faire suivre le message a tous les autres clients :
            #for cle in listeJoueur:
            #    if cle != nom:      # ne pas le renvoyer a l'emetteur
            #        listeJoueur[cle].send(message)
        # Fermeture de la connexion :
        self.connexion.close()       # couper la connexion cote  serveur
        supp=listePartie[self.numPartie].deljoueur(self.connexion)
        if supp:
            print "supp partie"
            listePartie[self.numPartie].etat=-2
            #la partie est conservee mais etat a -2
            #-2 signifie que la partie est abandonnee
        del listeJoueur[nom] # supprimer son entree dans le dictionnaire
        print "Client %s deconnecte." % nom
        # Le thread se termine ici











# Initialisation du serveur - Mise en place du socket :
if __name__=="__main__":
    mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    host="localhost"
    port=4000
    if len(sys.argv)<2:
        print "default listen port : %d"%port
        print "default localhost : %s"%host
    elif len(sys.argv)==2:
        if len(sys.argv[1])>5:
            host = sys.argv[1]
            print "localhost given : %s"%host
        else:       
            port = int(sys.argv[1])
            print "listened port : %d"%port
    else:
        if len(sys.argv[1])>len(sys.argv[2]):
            host = sys.argv[1]
            port = int(sys.argv[2])
        else:
            host = sys.argv[2]
            port = int(sys.argv[1])
    
        print "host given: %s"%host
        print "listened port: %d"%port

    try:
        mySocket.bind((host,port))
    except socket.error:
        print "La liaison du socket a l'adresse choisie a echoue."
        sys.exit()
    print "Serveur pret, en attente de requetes ..."
    mySocket.listen(15)
# Attente et prise en charge des connexions demandees par les clients :         
    while 1:
        connexion, adresse = mySocket.accept()
    # Creer un nouvel objet thread pour gerer la connexion :
        th = ThreadClient(connexion)
        th.start()
    # Memoriser la connexion dans le dictionnaire :
        it = th.getName()        # identifiant du thread
        listeJoueur[it] = connexion
        print "Client %s connecte, adresse IP %s, port %s." %\
            (it, adresse[0], adresse[1])
    # Dialogue avec le client :
        connexion.send("Vous etes connecte. Envoyez vos messages.")

